package com.shijie.service;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;

import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import tk.mybatis.mapper.entity.Condition;
import tk.mybatis.mapper.entity.Example;

import com.shijie.component.ErpUserService;
import com.shijie.core.AbstractService;
import com.shijie.core.ServiceException;
import com.shijie.domain.entity.AdminRoles;
import com.shijie.domain.entity.Menus;
import com.shijie.domain.entity.RoleMenus;
import com.shijie.domain.entity.Roles;
import com.shijie.domain.enums.EnumInterface.Status;
import com.shijie.mapper.AdminRolesMapper;
import com.shijie.mapper.MenusMapper;
import com.shijie.mapper.RoleMenusMapper;
import com.shijie.mapper.RolesMapper;
import com.shijie.utils.TreeUtil;

/*
 *  @author: smart boy
 *  @date: 2018-08-06
 */
@Service
public class RolesService extends AbstractService<Roles> {

	@Resource
	private RolesMapper rolesMapper;
	@Resource
	private AdminRolesMapper adminRolesMapper;
	@Resource
	private RoleMenusMapper roleMenusMapper;
	@Resource
	private MenusMapper menusMapper;
	@Autowired
	private ErpUserService erpUserService;
	@Resource
	private AdminRolesService adminRolesService;
	
	public Set<String> selectPermsByUserId(Integer userId){
		Set<String> permission = new HashSet<>();
		List<Menus> menus = this.getMenuListByUserId(userId);
		//只存储了跟结点。菜单渲染时，如果没有子结点但是无父结点，则关联查询
		List<Menus> newMenus = new ArrayList<>();
		for(Menus m : menus){
			this.component(menus, m, newMenus);
		}
		menus.addAll(newMenus);
		
		for(Menus menu : menus){
			if(menu !=null){
				permission.add(menu.getPerms());
			}
		}
		return permission;
	}
	
	public Set<Integer> getRoleMenuIdList(Integer roleId){
		Example condition = new Example(RoleMenus.class);
		condition.createCriteria().andEqualTo("roleId", roleId);
		List<RoleMenus> roleMenus = roleMenusMapper.selectByCondition(condition);
		Set<Integer> menuIds = new HashSet<>();
		roleMenus.forEach(c->{
			menuIds.add(c.getMenuId());
		});
		return menuIds;
	}
	public List<Menus> getMenusByUserId(Integer userId) throws ServiceException{
		return TreeUtil.tree(this.getMenuListByUserId(userId));
	}
	public List<Roles> getRolesByUserId(Integer userId) throws ServiceException{
		AdminRoles ar = new AdminRoles();
		ar.setUserId(userId);
		List<AdminRoles> adminRoles = adminRolesMapper.select(ar);
		if(adminRoles.size()<0){
			throw new ServiceException(String.format("%用户不存在操作权限的角色！", userId));
		}
		List<Roles> roleIdList = new ArrayList<>();
		for(AdminRoles adminRole :adminRoles ){
			Roles roles = rolesMapper.selectByPrimaryKey(adminRole.getRoleId());
			roleIdList.add(roles);
		}
		return roleIdList;
	}
	
	public List<Menus> getMenuListByUserId(Integer userId){
		if(userId == 1L){
			Example con = new Example(Menus.class);
			con.createCriteria().andEqualTo("visible",0);
			return menusMapper.selectByCondition(con);
		}
		AdminRoles ar = new AdminRoles();
		ar.setUserId(userId);
		List<AdminRoles> adminRoles = adminRolesMapper.select(ar);
		if(adminRoles.size()<0){
			throw new ServiceException(String.format("%用户不存在操作权限的角色！", userId));
		}
		List<Integer> roleIdList = new ArrayList<>();
		for(AdminRoles adminRole :adminRoles ){
			roleIdList.add(adminRole.getRoleId());
		}
		Example condition = new Example(RoleMenus.class);
		condition.createCriteria().andIn("roleId", roleIdList);
		List<RoleMenus> roleMenus = roleMenusMapper.selectByCondition(condition);
		List<Integer> menuIdList = new ArrayList<>();
		for(RoleMenus roleMenu :roleMenus ){
			menuIdList.add(roleMenu.getMenuId());
		}
		
		Example conditionx = new Example(RoleMenus.class);
		conditionx.createCriteria().andIn("id", menuIdList);
		List<Menus> menus = menusMapper.selectByCondition(conditionx);

		//只存储了跟结点。菜单渲染时，如果没有子结点但是无父结点，则关联查询
				List<Menus> newMenus = new ArrayList<>();
				for(Menus m : menus){
					this.component(menus, m, newMenus);
				}
				menus.addAll(newMenus);
				
		return menus;
	}
	
	public void component (List<Menus> menus,Menus m,List<Menus> newMenus ){
		if(m.getParentId() >0 && !this.haContains(menus, m.getParentId())){
			Menus cm = menusMapper.selectByPrimaryKey(m.getParentId());
			newMenus.add(cm);
			if(cm.getParentId() >0){
				this.component(menus, cm, newMenus);
			}
		}
	}
	private boolean haContains(List<Menus> menus,Integer parentId){
		for(Menus m : menus){
			if(parentId.intValue() == m.getId().intValue()){
				return Boolean.TRUE;
			}
		}
		return Boolean.FALSE;
	}
	@Transactional
	public void saveOrderUpdateRoles(Roles roles) throws ServiceException{
				if(roles.getMenuIdList().size() <1){
					throw new ServiceException("请选择权限菜单!");
				}
				if(roles.getId() == null){
					roles.setStatus(Status.VALID.ordinal());
					roles.setCreateBy(erpUserService.getUserName());
					roles.setCreateTime(DateTime.now().toDate());
					rolesMapper.insert(roles);
					List<RoleMenus> roleMenusList = new ArrayList<>();
					for(Integer menuId : roles.getMenuIdList()){
						RoleMenus roleMenus = new RoleMenus();
						roleMenus.setRoleId(roles.getId());
						roleMenus.setMenuId(menuId);
						roleMenusList.add(roleMenus);
					}
					roleMenusMapper.insertList(roleMenusList);
				}else{
					Roles role = rolesMapper.selectByPrimaryKey(roles.getId());
					role.setUpdateBy(erpUserService.getUserName());
					role.setUpdateTime(DateTime.now().toDate());
					role.setRoleName(roles.getRoleName());
					role.setRoleSort(roles.getRoleSort());
					rolesMapper.updateByPrimaryKey(role);
					Example condition = new Example(RoleMenus.class);
					condition.createCriteria().andEqualTo("roleId", roles.getId());
					roleMenusMapper.deleteByCondition(condition);
					List<RoleMenus> roleMenusList = new ArrayList<>();
					for(Integer menuId : roles.getMenuIdList()){
						RoleMenus roleMenus = new RoleMenus();
						roleMenus.setRoleId(roles.getId());
						roleMenus.setMenuId(menuId);
						roleMenusList.add(roleMenus);
					}
					roleMenusMapper.insertList(roleMenusList);
				}
	}
	
	public void deleteById(Integer id) throws ServiceException{
		//是否被占用
		Condition condition = new Condition(AdminRoles.class);
		condition.createCriteria().andEqualTo("roleId", id);
		List<AdminRoles> list = adminRolesService.selectByCondition(condition);
		if(list.size() >0){
			throw new ServiceException("该角色不能删除，已被占用！");
		}
		rolesMapper.deleteByPrimaryKey(id);
		Example condition2 = new Example(RoleMenus.class);
		condition2.createCriteria().andEqualTo("roleId", id);
		roleMenusMapper.deleteByCondition(condition2);
	}
}
